<template>
	<zh-sheet :transprent="props.transprent" :margin="props.margin" :padding="props.padding">
		<zh-sheet :margin="[0, 0]" :padding="[0, 0]" :transprent="props.transprent" :round="props.round"
			:text="props.text" :color="_color">
			<view class="flex-row-center-end" style="width: 100%" :style="{ 'min-height': _height + 'rpx' }">
				<view class="pl-10" style="width: 100%"
					:class="props.inputAlign === 'left' ? 'flex-row-center-start' : 'flex-row-center-end'"
					@click="onClick">
					<zh-text unit="px" :color="allAttrs.disabled ? '#8799a3' : propsDetail.fontColor"
						:font-size="propsDetail.fontSize_px" v-if="_strvalue" :label="_strvalue"></zh-text>
					<zh-text color="#9E9E9E" v-if="!_strvalue" unit="px" :font-size="propsDetail.fontSize_px"
						:label="props.placeholder"></zh-text>
				</view>
				<tm-icon v-if="!allAttrs.disabled && props.showClear && _value" class="pl-10"
					:font-size="props.fontSize" name="tmicon-times-circle-fill" @click="onclear"> </tm-icon>
				<tm-icon class="pl-10 pr-2" :color="allAttrs.disabled ? '#8799a3' : propsDetail.fontColor"
					:font-size="props.fontSize" name="tmicon-angle-right" @click="onClick">
				</tm-icon>
			</view>
		</zh-sheet>

		<zh-picker v-if="state.myType === 'picker'" :columns="myOptions" v-bind="allAttrs" :height="propsDetail.drawerHeight"
			:fieldNames="props.fieldNames" :showSearch="false" :color="props.pickerColor" v-model="_value"
			v-model:model-str="_strvalue" v-model:show="show" :default-value="_value" @confirm="onConfirm"></zh-picker>
		<selectPanelVue v-if="state.myType === 'list'" :columns="props.options" v-bind="allAttrs" :height="propsDetail.drawerHeight"
			:showSearch="showSearch" :color="props.pickerColor" v-model="_value" v-model:model-str="_strvalue"
			v-model:show="show" :max="props.max" :mode="props.mode" :lazy="props.lazy" :default-value="_value"
			:fieldNames="props.fieldNames" :queryParams="props.queryParams" :funcCode="props.funcCode" :url="url"
			:cryptoEnabled="props.cryptoEnabled" :repeatEnabled="props.repeatEnabled"
			:desensitizeFlag="props.desensitizeFlag" :searchField="props.searchField" :dictField="dictField"
			:searchParams="props.searchParams" :timeout="props.timeout" @confirm="onConfirm"></selectPanelVue>
		<treePanelVue v-if="state.myType === 'tree'" :columns="myOptions" v-bind="allAttrs" :height="propsDetail.drawerHeight"
			:checkStrictly="props.checkStrictly" :checkable="props.checkable" :expandedAll="props.expandedAll"
			:queryParams="props.queryParams" :fieldNames="props.fieldNames" :showSearch="showSearch"
			:color="props.pickerColor" v-model="_value" v-model:model-str="_strvalue" v-model:show="show"
			:funcCode="props.funcCode" :url="props.url" :cryptoEnabled="props.cryptoEnabled"
			:repeatEnabled="props.repeatEnabled" :desensitizeFlag="props.desensitizeFlag" :timeout="props.timeout"
			:data="props.options" :max="props.max" :mode="props.mode" :lazy="props.lazy" :default-value="_value"
			@confirm="onConfirm"></treePanelVue>
	</zh-sheet>
</template>

<script lang="ts" setup name="zh-select">
	import { computed, PropType, ref, watch, useAttrs, defineEmits, toRaw } from 'vue';
	import { toLine } from '@/common/utils/util';
	import selectPanelVue from './select-panel.vue';
	import treePanelVue from './tree-panel.vue';
	import http from '@/common/utils/http';
	import systemConfigStore from '@/store/modules/systemConfigStore';
	const store = systemConfigStore();
	const props = defineProps({
		followTheme: {
			type: [Boolean, String],
			default: false,
		},
		//默认的聚集状态
		focus: {
			type: Boolean,
			default: false,
		},
		height: {
			type: Number,
			default: 64,
		},
		text: {
			type: Boolean,
			default: true,
		},
		fieldNames: {
			type: Object,
			default: () => { },
		},
		margin: {
			type: Array as PropType<Array<number>>,
			default: () => [0, 0],
		},
		round: {
			type: Number,
			default: 3,
		},
		transprent: {
			type: [Boolean, String],
			default: true,
		},
		placeholder: {
			type: String,
			default: '请选择',
		},
		showClear: {
			type: Boolean,
			default: true,
		},
		fontSize: {
			type: Number,
			default: 30,
		},
		padding: {
			type: Array as PropType<Array<number>>,
			default: () => [0, 0],
		},
		options: {
			type: Array,
			default: () => {
				return [];
			},
		},
		modelValue: {
			type: [Number, String, Boolean, Array],
			default: undefined,
		},
		inputAlign: {
			type: String,
			default: '',
		},
		/**
		 * 注意：这里是单向输出显示的value值，而不是modelValue的index索引值。
		 * 这里主要是为了方便表单上页面的显示。如果真要保存到数据库，你应该保存modelValue的值。
		 */
		modelStr: {
			type: [String],
			default: '',
		},
		pickerColor: {
			type: String,
			default: 'primary',
		},
		color: {
			type: String,
			default: 'grey-darken-2',
		},
		//激活时的主题配色。
		focusColor: {
			type: String,
			default: 'primary',
		},
		//默认使用自动配色
		fontColor: {
			type: String,
			default: '',
		},
		type: {
			type: String,
			default: 'picker',
		},
		//	使单选模式可搜索
		showSearch: {
			type: Boolean,
			default: true,
		},
		lazy: {
			type: Boolean,
			default: false,
		},
		max: {
			type: Number,
			default: 99,
		},
		//查询附带参数
		searchParams: {
			type: Object,
			default() {
				return {
					tableName: 'sys_dict',
					resultList: [],
					queryList: [],
					pageNum: 1,
					pageSize: 20,
				};
			},
		},
		//查询url
		url: {
			type: String,
			default() {
				return '';
			},
		},
		//查询功能编号
		funcCode: {
			type: String,
			default() {
				return '';
			},
		},
		//查询数据字典字段
		dictField: {
			type: String,
			default() {
				return '';
			},
		},
		//查询主字段名称
		searchField: {
			type: String,
			default() {
				return '';
			},
		},
		//模式：单选 single或者多选multiple
		mode: {
			type: String,
			default: 'single',
		},
		//单选模式下是否使用picker显示
		pickerFlag: {
			type: Boolean,
			default: true,
		},
		queryParams: {
			type: Object,
			default: () => { },
		},
		//是否展开所有
		expandedAll: {
			type: Boolean,
			default: false,
		},
		//在显示复选框的情况下，是否严格的遵循父子不互相关联的做法，默认为 false
		checkStrictly: {
			type: Boolean,
			default: false,
		},
		//允许在节点前添加复选框。
		checkable: {
			type: Boolean,
			default: true,
		},
		timeout: Number,
		//是否加密
		cryptoEnabled: {
			type: Boolean,
			default: false
		},
		//是否脱敏
		desensitizeFlag: {
			type: Boolean,
			default: false
		},
		//是否防重复提交
		repeatEnabled: {
			type: Boolean,
			default: false
		},
		extend: {
			// 扩展属性，对象形式，存放组件的扩展属性
			type: Object,
			default: () => {
				return {};
			},
		},
	});
	const attrs = useAttrs();
	const emits = defineEmits(['update:modelValue', 'update:modelStr', 'clear', 'confirm']);
	const allAttrs = computed(() => {
		return Object.assign(props.extend, attrs);
	});
	const _height = computed(() => (store.uiStyle === 'elder' ? props.height + 20 : props.height));
	const propsDetail = computed(() => {
		const systemInfo=uni.getSystemInfoSync();
		const windowHeight = systemInfo.windowHeight;
		let drawerHeight=0;
		if(store.orientation === 'landscape'){
			drawerHeight=(windowHeight/(uni.upx2px(100)/100))-20;
		}else{
			drawerHeight=(windowHeight/(uni.upx2px(100)/100))-400;
		}
		 
		return {
			...props,
			drawerHeight:drawerHeight,
			fontColor: allAttrs.value.disabled ? '#8799a3' : props.fontColor || props.color,
			fontSize_px: uni.upx2px(store.uiStyle === 'elder' ? Number(props.fontSize) + 20 : props.fontSize)
		};
	});
	//是否聚焦中。
	const _foucsActive = ref(props.focus || false);
	watch(
		() => props.focus,
		() => {
			_foucsActive.value = props.focus;
		}
	);
	const _color = computed(() => {
		let color = props.color;
		if (_foucsActive.value) {
			if (props.followTheme && store.color) {
				color = store.color;
			} else {
				color = props.focusColor;
			}
		}
		return color;
	});
	const nodeLabel = computed(() => {
		if (props.fieldNames.bindLabel) {
			return props.fieldNames.bindLabel;
		}
		return props.fieldNames.label;
	});
	const nodeValue = computed(() => {
		if (props.fieldNames.bindValue) {
			return props.fieldNames.bindValue;
		}
		return props.fieldNames.value;
	});
	const show = ref(false);
	const _value = ref<any>(props.modelValue);
	const _strvalue = ref(props.modelStr);
	const myOptions = ref<any>([]);
	const allOptions = ref<any>([]);

	const state = reactive({
		hasNextPage: true, //是否还有分页数据
		myLoading: false,
		myType: props.type,
	});
	let tmid : any = NaN;
	function onConfirm(value : any, selectList : any) {
		clearTimeout(tmid);
		emits('update:modelStr', _strvalue.value);
		emits('update:modelValue', value);
		tmid = setTimeout(() => {
			emits('confirm', value, selectList);
		}, 50);
	}
	function onclear() {
		_value.value = undefined;
		_strvalue.value = '';
		emits('update:modelStr', _strvalue.value);
		emits('update:modelValue', undefined);
		emits('clear');
	}
	function onClick() {
		if (allAttrs.value.disabled) {
			return;
		}
		clearTimeout(tmid);
		tmid = setTimeout(() => {
			show.value = true;
		}, 30);
	}
	onMounted(() => {
		if (props.options) {
			myOptions.value = props.options;
			allOptions.value = props.options;
		}
		if (props.mode === 'multiple' && props.type === 'picker') {
			state.myType = 'list';
		}
		if (props.lazy) {
			if (state.myType === 'picker') {
				onSearch(null, 'top');
			} else if (state.myType === 'tree') {
				getTreeData();
			}
		}
	});
	const getTreeData = () => {
		let url = props.url;
		let config : any = {};
		if (props.timeout && props.timeout > 0) {
			config.timeout = props.timeout;
		}
		let headers = {} as any
		headers.cryptoEnabled = props.cryptoEnabled
		headers.repeatEnabled = props.repeatEnabled
		headers.desensitizeFlag = props.desensitizeFlag
		if (props.funcCode) {
			headers['func-code'] = props.funcCode;
			url = $api.common.send.url + props.funcCode;
		}
		config.header = headers;
		if (url) {
			http
				.post(url, props.queryParams)
				.then((res : any) => {
					if (!Array.isArray(res.result)) {
						myOptions.value = res.result.treeList || [];
					} else {
						myOptions.value = res.result || [];
					}
					state.hasNextPage = false;
				})
				.catch(() => { });
		}
	};
	const onSearch = (searchText : any, type : any) => {
		if (!props.lazy) {
			if (searchText) {
				let list = allOptions.value.filter((item : any) => (typeof item == 'string' ? item.indexOf(searchText) >= 0 : item[nodeLabel.value].indexOf(searchText) >= 0));
				myOptions.value = list;
			} else {
				myOptions.value = allOptions.value;
			}
			return;
		}
		let mySearchParams = Object.assign(props.searchParams, {
			tableName: 'sys_dict',
			resultList: [],
			queryList: [],
			pageNum: 1,
			pageSize: 20,
		});

		if (type === 'top') {
			mySearchParams.pageNum = 1;
		}
		if (!mySearchParams.tableName) {
			mySearchParams.tableName = 'sys_dict';
		}
		let searchField = props.searchField;
		if (!searchField) {
			searchField = toLine(nodeLabel.value);
		}
		mySearchParams.keyName = nodeLabel.value;
		mySearchParams.valueName = nodeValue.value;
		mySearchParams.searchField = searchField;
		mySearchParams.searchText = searchText;
		mySearchParams[props.searchField] = searchText;
		if (props.queryParams) {
			mySearchParams = Object.assign(mySearchParams, props.queryParams);
		}
		let config : any = {};
		if (props.timeout && props.timeout > 0) {
			config.timeout = props.timeout;
		}
		let searchUrl = $api.common.getDictSearchData.url;
		let headers = {} as any
		headers.cryptoEnabled = props.cryptoEnabled
		headers.repeatEnabled = props.repeatEnabled
		headers.desensitizeFlag = props.desensitizeFlag
		if (props.funcCode) {
			headers['func-code'] = props.funcCode;
			searchUrl = $api.common.send.url + props.funcCode;
		} else {
			if (props.url) {
				searchUrl = props.url;
			} else if (props.dictField) {
				headers['func-code'] = 'dict0011';
				searchUrl = $api.common.send.url + 'dict0011';
				mySearchParams.dictField = props.dictField;
			}
		}
		config.header = headers;
		http
			.post(searchUrl, mySearchParams, config)
			.then((res : any) => {
				if (mySearchParams.pageNum === 1) {
					if (!Array.isArray(res.result)) {
						myOptions.value = res.result.list || [];
						mySearchParams.pageNum = mySearchParams.pageNum + 1;
						state.hasNextPage = res.result.hasNextPage;
						if (state.hasNextPage) {
							state.myType = 'list';
						}
					} else {
						myOptions.value = res.result;
						state.hasNextPage = false;
					}
				} else {
					myOptions.value = myOptions.value.concat(res.result.list || []);
					mySearchParams.pageNum = mySearchParams.pageNum + 1;
					state.hasNextPage = res.result.hasNextPage;
				}
				allOptions.value = [...myOptions.value];
			})
			.catch(() => { });
	};
	//------------------监听--------------------------------
	watch(
		() => props.modelValue,
		(val) => {
			_value.value = val;
		},
		{
			deep: true,
		}
	);
	watch(
		() => props.modelStr,
		(val) => {
			_strvalue.value = val;
		},
		{
			deep: true,
		}
	);
	watch(
		() => props.options,
		(val) => {
			if (props.options && props.options.length > 0) {
				myOptions.value = props.options;
				allOptions.value = props.options;
			} else {
				myOptions.value = [];
				allOptions.value = [];
			}
		},
		{
			deep: true,
		}
	);
</script>

<style scoped></style>